package com.dries.portal.module.chat.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dries.common.api.CommonResult;
import com.dries.portal.module.user.entity.UserEntity;
import com.dries.portal.module.chat.constants.ChatConstant;
import com.dries.portal.module.chat.entity.Chat;
import com.dries.portal.module.chat.entity.RecentChat;
import com.dries.portal.module.chat.enums.MsgAction;
import com.dries.portal.module.chat.service.IRecentChatService;
import com.dries.portal.module.user.service.UserService;
import com.dries.security.service.RedisService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.security.Principal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description:
 * @Author ZSY
 * @createTime 2020/8/18 16:37
 */
@Slf4j
@Api(tags = "聊天服务API", value = "GreetingController")
@RestController
public class GreetingController {

    @Resource
    private RedisService redisService;
    @Resource
    private UserService userService;
    @Resource
    private IRecentChatService recentChatService;

    @Resource
    private SimpMessagingTemplate messagingTemplate;

    @MessageMapping("/group")
    public void sendToGroup(Chat chat) {

        chat.setMsgId(IdUtil.simpleUUID());
        chat.setCreateTime(new Date());
        String key = ChatConstant.CHAT_GROUP_MESSAGE + chat.getTo();
        redisService.lPush(key, chat, 604800);

        RecentChat recentChat = recentChatService.getOne(new QueryWrapper<RecentChat>().lambda()
                .eq(RecentChat::getAccept, chat.getTo())
                .eq(RecentChat::getSender, chat.getFrom())
        );

        if (recentChat != null) {
            recentChat.setMsg(chat.getContent().get(0).getContent());
            recentChatService.updateById(recentChat);
        } else {
            recentChat = new RecentChat(chat.getTo(), chat.getFrom(), chat.getContent().get(0).getContent(),MsgAction.GROUP_CHAT_MSG.getCode());
            recentChatService.save(recentChat);
        }

        System.out.println("接收到群消息==================》" + JSONUtil.toJsonStr(chat));
        messagingTemplate.convertAndSend("/topic/" + chat.getTo(), chat);
    }

    @MessageMapping("/chat")
    public void sendToUser(Principal principal,Chat chat) {

        chat.setMsgId(IdUtil.simpleUUID());
        chat.setCreateTime(new Date());
        String key = ChatConstant.CHAT_MESSAGE + chat.getFrom() + ":" + chat.getTo();
        redisService.lPush(key, chat, 604800);

        RecentChat recentChat = recentChatService.getOne(new QueryWrapper<RecentChat>().lambda()
                .eq(RecentChat::getAccept, chat.getTo())
                .eq(RecentChat::getSender, chat.getFrom())
        );
        RecentChat recentChatTo = recentChatService.getOne(new QueryWrapper<RecentChat>().lambda()
                .eq(RecentChat::getSender, chat.getTo())
                .eq(RecentChat::getAccept, chat.getFrom())
        );
        if (recentChat != null ) {
            recentChat.setMsg(chat.getContent().get(0).getContent());
            recentChatService.updateById(recentChat);
        } else {
            recentChat = new RecentChat(chat.getTo(), chat.getFrom(), chat.getContent().get(0).getContent(),MsgAction.CHAT_MSG.getCode());
            recentChatService.save(recentChat);
        }
        if (recentChatTo != null ) {
            recentChatTo.setMsg(chat.getContent().get(0).getContent());
            recentChatService.updateById(recentChatTo);
        } else {
            recentChatTo = new RecentChat(chat.getFrom(), chat.getTo(), chat.getContent().get(0).getContent(),MsgAction.CHAT_MSG.getCode());
            recentChatService.save(recentChatTo);
        }

        System.out.println("接收到私聊消息==================》" + JSONUtil.toJsonStr(chat));
        log.info("【当前登录用户=========》 {}】 ", principal.getName());
        messagingTemplate.convertAndSendToUser(chat.getTo(), "/queue/chat", chat);
    }

    @MessageMapping("/all")
    public void sendToAll(Chat chat) {
        chat.setMsgId(IdUtil.simpleUUID());
        System.out.println("发送全体消息==================》" + JSONUtil.toJsonStr(chat));
        messagingTemplate.convertAndSend("/all", chat);
    }

    @ApiOperation("获取当前在线人数")
    @GetMapping("/chat/online")
    public CommonResult getOnlineChat() {
        Set<String> onlineChat = (Set<String>) redisService.get(ChatConstant.CHAT_ONLINE_KEY);
        return CommonResult.success(onlineChat);
    }

    @ApiOperation("加入群聊")
    @GetMapping("/chat/join/chat/{roomId}")
    public CommonResult joinChatRoom(Principal principal, @PathVariable String roomId) {

        UserEntity data = userService.getCurrentUser().getData();
        redisService.sAdd(ChatConstant.CHAT_GROUP_ONLINE_KEY + roomId, principal.getName());
        redisService.sAdd(ChatConstant.CONVENER_USER_KEY + data.getUserid(), roomId);

        return CommonResult.success();
    }

    @ApiOperation("离开群聊")
    @GetMapping("/chat/leave/chat/{roomId}")
    public CommonResult leaveChatRoom(Principal principal, @PathVariable String roomId) {
        // redisService.sAdd(ChatConstant.CHAT_GROUP_ONLINE_KEY + roomId, principal.getName());
        redisService.sRemove(ChatConstant.CHAT_GROUP_ONLINE_KEY + roomId, principal.getName());
        return CommonResult.success();
    }

    @ApiOperation("获取当前群聊在线人数")
    @GetMapping("/chat/online/group/{roomId}")
    public CommonResult getOnlineChatRoom(@PathVariable String roomId) {
        Set<Object> objects = redisService.sMembers(ChatConstant.CHAT_GROUP_ONLINE_KEY + roomId);
        log.info(JSONUtil.toJsonStr(objects));
        return CommonResult.success(objects.size());
    }

    @ApiOperation("获取群聊记录")
    @GetMapping("/chat/msg/{roomId}")
    public CommonResult getGroupMessage(@PathVariable String roomId) {
        List<Object> msgChats = redisService.lRange(ChatConstant.CHAT_GROUP_MESSAGE + roomId, 0, -1);
        return CommonResult.success(msgChats);
    }

    @ApiOperation("获取私聊记录")
    @GetMapping("/chat/msg/{username}/{receiver}")
    public CommonResult getMessage(@PathVariable String username, @PathVariable String receiver) {

        List<Object> msg_my =  redisService.lRange(ChatConstant.CHAT_MESSAGE + username + ":" + receiver, 0, -1);
        List<Object> msg_your = redisService.lRange(ChatConstant.CHAT_MESSAGE + receiver + ":" + username, 0, -1);

        List<Object> collect = Stream.of(msg_my, msg_your)
                .flatMap(Collection::stream)
                .distinct()
                .collect(Collectors.toList());

        List<Chat> list = collect.stream().map(e -> (Chat) e).sorted(Comparator.comparing(Chat::getCreateTime)).collect(Collectors.toList());

        return CommonResult.success(list);
    }


}
